﻿// win32.cpp : Defines the entry point for the application. 定义应用程序的入口点。
//

#include "stdafx.h"								//包含 stdafx.h 头文件
#include "resource.h"							//包含 resource.h 头文件
#include <windows.h>

//非c语言自带的类型定义
#define CALLBACK    __stdcall					//被这个关键字修饰的函数，其参数都是从右向左通过堆栈传递的
#define DECLARE_HANDLE(name) struct name##__{int unused;}; typedef struct name##__ *name
typedef int		BOOL;
typedef wchar_t WCHAR;
typedef WCHAR TCHAR;
DECLARE_HANDLE(HINSTANCE);
typedef void *HANDLE;
typedef unsigned short	WORD;
typedef WORD	ATOM;
typedef _W64 long LONG_PTR;
typedef LONG_PTR            LRESULT;
DECLARE_HANDLE(HWND);
typedef unsigned int	UINT;
typedef unsigned int	WPARAM;
typedef long	LPARAM;
typedef unsigned long	DWORD;
DECLARE_HANDLE(HACCEL);
typedef long	LRESULT;

#ifndef FALSE
#define FALSE	0			//如果FALSE未被定义，则定义为0 
#endif

#ifndef TRUE
#define TRUE	1			//如果TRUE未被定义，则定义为1
#endif

typedef struct tagMSG {
	HWND        hwnd;
	UINT        message;
	WPARAM      wParam;
	LPARAM      lParam;
	DWORD       time;
	POINT       pt;
#ifdef _MAC
	DWORD       lPrivate;
#endif
} MSG, *PMSG, NEAR *NPMSG, FAR *LPMSG;

typedef struct tagPOINT
{
	LONG  x;
	LONG  y;
} POINT, *PPOINT, NEAR *NPPOINT, FAR *LPPOINT;

#define MAX_LOADSTRING 100						//字符串最大长度

// Global Variables:全局变量: 
HINSTANCE hInst;								// current instance 当前实例句柄
TCHAR szTitle[MAX_LOADSTRING];					// The title bar text 窗口标题名
TCHAR szWindowClass[MAX_LOADSTRING];			//  The title bar text 窗口类名

// Foward declarations of functions included in this code module: 此代码模块中包含的函数的前向声明: 
ATOM				MyRegisterClass(HINSTANCE hInstance);			//注册窗口类
BOOL				InitInstance(HINSTANCE, int);					//保存实例句柄并创建主窗口
LRESULT CALLBACK	WndProc(HWND, UINT, WPARAM, LPARAM);			//处理主窗口的消息
LRESULT CALLBACK	About(HWND, UINT, WPARAM, LPARAM);				//“关于”框的消息处理程序

int APIENTRY WinMain(HINSTANCE hInstance,
				     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)							//Windows应用程序的入口
{
 	// TODO: Place code here. 在此放置代码。
	MSG msg;
	HACCEL hAccelTable;

	// Initialize global strings 初始化全局字符串
	 (hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
	LoadString(hInstance, IDC_WIN32, szWindowClass, MAX_LOADSTRING);// LoadString 从资源里加载字符串资源到CString对象里
	MyRegisterClass(hInstance);// MyRegisterClass 函数用于注册该窗口应用程序

	// Perform application initialization: 执行应用程序初始化: 
	if (!InitInstance (hInstance, nCmdShow)) //如果初始化成功，则返回非零值；否则返回0。
	{
		return FALSE;
	}

	hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_WIN32);

	// Main message loop: 主消息循环: 
	while (GetMessage(&msg, NULL, 0, 0)) // GetMessage 从消息队列中取得一条消息，并将消息放在一个MSG结构中
	{
		if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) // TranslateAccelerator 翻译加速键表
		{
			TranslateMessage(&msg);// TranslateMessage 函数用于将虚拟键消息转换为字符消息
			DispatchMessage(&msg);// DispatchMessage 该函数分发一个消息给窗口程序
		}
	}

	return msg.wParam;
}



//
//  FUNCTION: MyRegisterClass()
//
//  PURPOSE: Registers the window class.  目的: 注册窗口类。
//
//  COMMENTS:
//
//    This function and its usage is only necessary if you want this code
//    to be compatible with Win32 systems prior to the 'RegisterClassEx'
//    function that was added to Windows 95. It is important to call this function
//    so that the application will get 'well formed' small icons associated
//    with it.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
	WNDCLASSEX wcex;

	wcex.cbSize = sizeof(WNDCLASSEX); 

	wcex.style			= CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc	= (WNDPROC)WndProc;
	wcex.cbClsExtra		= 0;
	wcex.cbWndExtra		= 0;
	wcex.hInstance		= hInstance;
	wcex.hIcon			= LoadIcon(hInstance, (LPCTSTR)IDI_WIN32);
	// LoadIcon 函数从与hInstance模块相关联的可执行文件中装入lpIconName指定的图标资源，
	//仅当图标资源还没有被装入时该函数才执行装入操作，否则只获取装入的资源句柄。
	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
	// LoadCursor 函数从一个与应用事例相关的可执行文件（EXE文件）中载入指定的光标资源。
	wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);
	wcex.lpszMenuName	= (LPCSTR)IDC_WIN32;
	wcex.lpszClassName	= szWindowClass;
	wcex.hIconSm		= LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);

	return RegisterClassEx(&wcex);// RegisterClassEx 函数为随后在调用Createwindow函数和CreatewindowEx函数中使用的窗口注册一个窗口类。
}

//
//   FUNCTION: InitInstance(HANDLE, int)
//
//   PURPOSE: Saves instance handle and creates main window 目的: 保存实例句柄并创建主窗口
//
//   COMMENTS:
//
//        In this function, we save the instance handle in a global variable and 在此函数中，我们在全局变量中保存实例句柄并
//        create and display the main program window.  创建和显示主程序窗口。
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   HWND hWnd;

   hInst = hInstance; // Store instance handle in our global variable  将实例句柄存储在全局变量中

   hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

   if (!hWnd)
   {
      return FALSE;
   }

   ShowWindow(hWnd, nCmdShow);// ShowWindow 函数设置指定窗口的显示状态
   UpdateWindow(hWnd);//如果窗口更新的区域不为空，UpdateWindow函数就发送一个WM_PAINT消息来更新指定窗口的客户区

   return TRUE;
}

//
//  FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
//
//  PURPOSE:  Processes messages for the main window. 处理主窗口的消息。
//
//  WM_COMMAND	- process the application menu - 处理应用程序菜单
//  WM_PAINT	- Paint the main window - 绘制主窗口
//  WM_DESTROY	- post a quit message and return - 发送退出消息并返回
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	int wmId, wmEvent;
	PAINTSTRUCT ps;
	HDC hdc;
	TCHAR szHello[MAX_LOADSTRING];
	LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);

	switch (message) 
	{
		case WM_COMMAND:
			wmId    = LOWORD(wParam); 
			wmEvent = HIWORD(wParam); 
			// Parse the menu selections: 分析菜单选择: 
			switch (wmId)
			{
				case IDM_ABOUT:
				   DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
				   break;
				case IDM_EXIT:
				   DestroyWindow(hWnd);
				   break;
				default:
				   return DefWindowProc(hWnd, message, wParam, lParam);
			}
			break;
		case WM_PAINT:
			hdc = BeginPaint(hWnd, &ps);
			// TODO: Add any drawing code here... 在此处添加使用的任何绘图代码...
			RECT rt;
			GetClientRect(hWnd, &rt);// GetClientRect 函数获取窗口客户区的大小
			DrawText(hdc, szHello, strlen(szHello), &rt, DT_CENTER); // DrawText 函数在指定的矩形里写入格式化的正文，根据指定的方法对正文格式化
			EndPaint(hWnd, &ps);
			break;
		case WM_DESTROY:
			PostQuitMessage(0);// EndPaint 是绘图的结束，释放绘图区
			break;
		default:
			return DefWindowProc(hWnd, message, wParam, lParam);// DefWindowProc 函数调用缺省的窗口过程来为应用程序没有处理的任何窗口消息提供缺省的处理
   }
   return 0;
}

// Mesage handler for about box. “关于”框的消息处理程序。
LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
	switch (message)
	{
		case WM_INITDIALOG:
				return TRUE;

		case WM_COMMAND:
			if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) 
			{
				EndDialog(hDlg, LOWORD(wParam));// EndDialog 函数清除一个模态对话框,并使系统中止对对话框的任何处理
				return TRUE;
			}
			break;
	}
    return FALSE;
}
